<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Spring Boot Actuator 深度解析 | 技术小馆</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            color: #333;
            line-height: 1.6;
        }
        .hero-gradient {
            background: linear-gradient(135deg, #6e8efb 0%, #a777e3 100%);
        }
        .code-block {
            background: #2d3748;
            color: #f8fafc;
            border-radius: 0.5rem;
            overflow: hidden;
        }
        .code-header {
            background: #1a202c;
            padding: 0.5rem 1rem;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .code-content {
            padding: 1rem;
            font-family: 'Courier New', Courier, monospace;
            font-size: 0.9rem;
            overflow-x: auto;
        }
        .section-divider {
            height: 1px;
            background: linear-gradient(90deg, transparent, rgba(0,0,0,0.1), transparent);
            margin: 3rem 0;
        }
        .floating-nav {
            position: sticky;
            top: 2rem;
        }
        .nav-link {
            transition: all 0.3s ease;
        }
        .nav-link:hover {
            color: #6e8efb;
            transform: translateX(5px);
        }
        .feature-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1);
        }
    </style>
</head>
<body class="bg-gray-50">
    <!-- Hero Section -->
    <section class="hero-gradient text-white py-20 px-4 md:px-0">
        <div class="container mx-auto max-w-5xl">
            <div class="flex flex-col md:flex-row items-center">
                <div class="md:w-1/2 mb-10 md:mb-0">
                    <h1 class="text-4xl md:text-5xl font-bold mb-4">Spring Boot Actuator</h1>
                    <h2 class="text-xl md:text-2xl font-medium mb-6">生产环境监控的艺术</h2>
                    <p class="text-lg opacity-90 mb-8">深入剖析Spring Boot为微服务架构提供的强大监控能力，掌握应用健康检查、性能指标监控与自定义扩展的最佳实践。</p>
                    <div class="flex space-x-4">
                        <a href="#overview" class="bg-white text-purple-600 px-6 py-2 rounded-md font-medium hover:bg-gray-100 transition duration-300">快速了解</a>
                        <a href="#implementation" class="border border-white text-white px-6 py-2 rounded-md font-medium hover:bg-white hover:text-purple-600 transition duration-300">实现原理</a>
                    </div>
                </div>
                <div class="md:w-1/2 flex justify-center">
                    <div class="bg-white bg-opacity-20 p-6 rounded-xl backdrop-blur-sm max-w-md">
                        <div class="mermaid">
                            graph TD
                                A[Spring Boot Actuator] --> B[健康检查]
                                A --> C[度量指标]
                                A --> D[环境信息]
                                A --> E[HTTP追踪]
                                B --> F[/actuator/health]
                                C --> G[/actuator/metrics]
                                D --> H[/actuator/env]
                                E --> I[/actuator/httptrace]
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <div class="container mx-auto max-w-5xl py-12 px-4 md:px-0">
        <div class="flex flex-col md:flex-row">
            <!-- Navigation -->
            <div class="md:w-1/4 pr-8 mb-10 md:mb-0">
                <div class="floating-nav bg-white p-6 rounded-xl shadow-sm">
                    <h3 class="font-bold text-lg mb-4 text-gray-700 border-b pb-2">文章导航</h3>
                    <ul class="space-y-3">
                        <li><a href="#overview" class="nav-link text-gray-600"><i class="fas fa-circle-notch mr-2 text-xs"></i> Actuator 概述</a></li>
                        <li><a href="#endpoints" class="nav-link text-gray-600"><i class="fas fa-plug mr-2 text-xs"></i> 端点实现</a></li>
                        <li><a href="#auto-config" class="nav-link text-gray-600"><i class="fas fa-cogs mr-2 text-xs"></i> 自动配置</a></li>
                        <li><a href="#customization" class="nav-link text-gray-600"><i class="fas fa-magic mr-2 text-xs"></i> 自定义扩展</a></li>
                        <li><a href="#configuration" class="nav-link text-gray-600"><i class="fas fa-wrench mr-2 text-xs"></i> 配置使用</a></li>
                    </ul>
                </div>
            </div>

            <!-- Content -->
            <div class="md:w-3/4">
                <!-- Overview Section -->
                <section id="overview" class="mb-16">
                    <div class="flex items-center mb-6">
                        <div class="w-2 h-8 bg-purple-600 mr-3"></div>
                        <h2 class="text-2xl font-bold text-gray-800">Spring Boot Actuator 概述</h2>
                    </div>
                    <p class="text-gray-700 mb-6">Spring Boot Actuator 是 Spring Boot 提供的一组生产环境监控功能，它为 Spring Boot 应用提供了许多关键指标、健康检查、应用状态等信息，帮助开发者更好地运维和监控应用。</p>
                    
                    <div class="grid md:grid-cols-2 gap-6 mb-8">
                        <div class="feature-card bg-white p-6 rounded-xl shadow-sm transition duration-300">
                            <div class="text-purple-600 mb-3"><i class="fas fa-heartbeat text-2xl"></i></div>
                            <h3 class="font-bold text-lg mb-2">健康监控</h3>
                            <p class="text-gray-600">实时监控应用健康状况，包括数据库连接、磁盘空间、缓存状态等关键指标。</p>
                        </div>
                        <div class="feature-card bg-white p-6 rounded-xl shadow-sm transition duration-300">
                            <div class="text-purple-600 mb-3"><i class="fas fa-chart-line text-2xl"></i></div>
                            <h3 class="font-bold text-lg mb-2">性能指标</h3>
                            <p class="text-gray-600">收集并暴露应用性能数据，如JVM内存使用、HTTP请求统计、数据库查询性能等。</p>
                        </div>
                    </div>

                    <h3 class="font-bold text-xl mb-4 text-gray-800 mt-10">核心端点</h3>
                    <div class="overflow-x-auto">
                        <table class="min-w-full bg-white rounded-lg overflow-hidden">
                            <thead class="bg-gray-100">
                                <tr>
                                    <th class="py-3 px-4 text-left text-gray-700 font-medium">端点</th>
                                    <th class="py-3 px-4 text-left text-gray-700 font-medium">描述</th>
                                    <th class="py-3 px-4 text-left text-gray-700 font-medium">默认启用</th>
                                </tr>
                            </thead>
                            <tbody class="divide-y divide-gray-200">
                                <tr>
                                    <td class="py-3 px-4"><code>/actuator/health</code></td>
                                    <td class="py-3 px-4">应用健康状态检查</td>
                                    <td class="py-3 px-4"><span class="text-green-500">是</span></td>
                                </tr>
                                <tr>
                                    <td class="py-3 px-4"><code>/actuator/metrics</code></td>
                                    <td class="py-3 px-4">应用性能指标</td>
                                    <td class="py-3 px-4"><span class="text-green-500">是</span></td>
                                </tr>
                                <tr>
                                    <td class="py-3 px-4"><code>/actuator/info</code></td>
                                    <td class="py-3 px-4">应用基本信息</td>
                                    <td class="py-3 px-4"><span class="text-red-500">否</span></td>
                                </tr>
                                <tr>
                                    <td class="py-3 px-4"><code>/actuator/env</code></td>
                                    <td class="py-3 px-4">应用环境变量</td>
                                    <td class="py-3 px-4"><span class="text-green-500">是</span></td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </section>

                <div class="section-divider"></div>

                <!-- Endpoints Implementation -->
                <section id="endpoints" class="mb-16">
                    <div class="flex items-center mb-6">
                        <div class="w-2 h-8 bg-purple-600 mr-3"></div>
                        <h2 class="text-2xl font-bold text-gray-800">Actuator 端点的实现</h2>
                    </div>
                    
                    <h3 class="font-bold text-xl mb-4 text-gray-800">2.1 端点的基本结构</h3>
                    <p class="text-gray-700 mb-6">Spring Boot Actuator 的每个端点实现都继承自 <code>AbstractEndpoint</code>，这个类为所有端点提供了基础功能，例如：初始化、响应请求等。</p>
                    
                    <div class="code-block mb-8">
                        <div class="code-header">
                            <span class="text-gray-300">Java</span>
                            <button class="text-gray-400 hover:text-white"><i class="far fa-copy"></i></button>
                        </div>
                        <div class="code-content">
                            <pre>public abstract class AbstractEndpoint&lt;T&gt; {
    private final String id;

    protected AbstractEndpoint(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }

    public abstract T invoke();
}</pre>
                        </div>
                    </div>

                    <h3 class="font-bold text-xl mb-4 text-gray-800">2.2 健康检查端点（/actuator/health）</h3>
                    <p class="text-gray-700 mb-6">健康检查是 Actuator 中一个非常重要的端点，它用来检查应用的健康状况。例如：数据库连接是否正常，缓存是否可用等。</p>
                    
                    <div class="code-block mb-8">
                        <div class="code-header">
                            <span class="text-gray-300">Java</span>
                            <button class="text-gray-400 hover:text-white"><i class="far fa-copy"></i></button>
                        </div>
                        <div class="code-content">
                            <pre>@Component
@Endpoint(id = "health")
public class HealthEndpoint extends AbstractEndpoint&lt;Health&gt; {

    private final HealthIndicatorRegistry healthIndicatorRegistry;

    public HealthEndpoint(HealthIndicatorRegistry healthIndicatorRegistry) {
        super("health");
        this.healthIndicatorRegistry = healthIndicatorRegistry;
    }

    @Override
    public Health invoke() {
        return this.healthIndicatorRegistry.getHealth();
    }
}</pre>
                        </div>
                    </div>

                    <h3 class="font-bold text-xl mb-4 text-gray-800">2.3 度量指标端点（/actuator/metrics）</h3>
                    <p class="text-gray-700 mb-6">度量指标端点用来暴露应用的性能指标，例如请求处理时间、数据库连接池的大小等。</p>
                    
                    <div class="code-block mb-8">
                        <div class="code-header">
                            <span class="text-gray-300">Java</span>
                            <button class="text-gray-400 hover:text-white"><i class="far fa-copy"></i></button>
                        </div>
                        <div class="code-content">
                            <pre>@Component
@Endpoint(id = "metrics")
public class MetricsEndpoint extends AbstractEndpoint&lt;MetricGroup&gt; {

    private final MeterRegistry meterRegistry;

    public MetricsEndpoint(MeterRegistry meterRegistry) {
        super("metrics");
        this.meterRegistry = meterRegistry;
    }

    @Override
    public MetricGroup invoke() {
        return new MetricGroup(meterRegistry.getMeters());
    }
}</pre>
                        </div>
                    </div>
                </section>

                <div class="section-divider"></div>

                <!-- Auto Configuration -->
                <section id="auto-config" class="mb-16">
                    <div class="flex items-center mb-6">
                        <div class="w-2 h-8 bg-purple-600 mr-3"></div>
                        <h2 class="text-2xl font-bold text-gray-800">Actuator 的自动配置与端点注册</h2>
                    </div>
                    
                    <h3 class="font-bold text-xl mb-4 text-gray-800">3.1 自动配置的核心类</h3>
                    <p class="text-gray-700 mb-6"><code>EndpointAutoConfiguration</code> 是 Spring Boot Actuator 自动配置的核心类。它负责将所有 <code>@Endpoint</code> 注解标注的类自动注册到 Spring 容器中。</p>
                    
                    <div class="code-block mb-8">
                        <div class="code-header">
                            <span class="text-gray-300">Java</span>
                            <button class="text-gray-400 hover:text-white"><i class="far fa-copy"></i></button>
                        </div>
                        <div class="code-content">
                            <pre>@Configuration
@ConditionalOnClass(Endpoint.class)
@Import(EndpointConfiguration.class)
public class EndpointAutoConfiguration {
}</pre>
                        </div>
                    </div>

                    <h3 class="font-bold text-xl mb-4 text-gray-800">3.2 端点注册</h3>
                    <p class="text-gray-700 mb-6">Spring Boot 会自动扫描类路径中带有 <code>@Endpoint</code> 注解的类，并将其作为 Bean 注册到 Spring 容器中。</p>
                    
                    <div class="code-block mb-8">
                        <div class="code-header">
                            <span class="text-gray-300">Java</span>
                            <button class="text-gray-400 hover:text-white"><i class="far fa-copy"></i></button>
                        </div>
                        <div class="code-content">
                            <pre>@Bean
public EndpointHandlerMapping endpointHandlerMapping(EndpointDiscoverer endpointDiscoverer) {
    return new EndpointHandlerMapping(endpointDiscoverer.getEndpoints());
}</pre>
                        </div>
                    </div>
                </section>

                <div class="section-divider"></div>

                <!-- Customization -->
                <section id="customization" class="mb-16">
                    <div class="flex items-center mb-6">
                        <div class="w-2 h-8 bg-purple-600 mr-3"></div>
                        <h2 class="text-2xl font-bold text-gray-800">Actuator 端点的自定义与扩展</h2>
                    </div>
                    
                    <h3 class="font-bold text-xl mb-4 text-gray-800">4.1 自定义端点</h3>
                    <p class="text-gray-700 mb-6">开发者只需通过 <code>@Endpoint</code> 注解创建一个新的端点类，然后将其注册为 Spring Bean 即可。</p>
                    
                    <div class="code-block mb-8">
                        <div class="code-header">
                            <span class="text-gray-300">Java</span>
                            <button class="text-gray-400 hover:text-white"><i class="far fa-copy"></i></button>
                        </div>
                        <div class="code-content">
                            <pre>@Component
@Endpoint(id = "custom")
public class CustomEndpoint extends AbstractEndpoint&lt;String&gt; {

    public CustomEndpoint() {
        super("custom");
    }

    @Override
    public String invoke() {
        return "This is a custom endpoint!";
    }
}</pre>
                        </div>
                    </div>

                    <h3 class="font-bold text-xl mb-4 text-gray-800">4.2 自定义健康指示器</h3>
                    <p class="text-gray-700 mb-6">开发者还可以创建自定义的健康检查指示器。自定义健康检查指示器需要实现 <code>HealthIndicator</code> 接口。</p>
                    
                    <div class="code-block mb-8">
                        <div class="code-header">
                            <span class="text-gray-300">Java</span>
                            <button class="text-gray-400 hover:text-white"><i class="far fa-copy"></i></button>
                        </div>
                        <div class="code-content">
                            <pre>@Component
public class CustomHealthIndicator implements HealthIndicator {

    @Override
    public Health health() {
        return Health.up().withDetail("customStatus", "Healthy").build();
    }
}</pre>
                        </div>
                    </div>
                </section>

                <div class="section-divider"></div>

                <!-- Configuration -->
                <section id="configuration" class="mb-16">
                    <div class="flex items-center mb-6">
                        <div class="w-2 h-8 bg-purple-600 mr-3"></div>
                        <h2 class="text-2xl font-bold text-gray-800">Spring Boot Actuator 的配置与使用</h2>
                    </div>
                    
                    <h3 class="font-bold text-xl mb-4 text-gray-800">启用和禁用端点</h3>
                    <p class="text-gray-700 mb-6">通过以下配置可以启用或禁用 Actuator 的端点。</p>
                    
                    <div class="code-block mb-8">
                        <div class="code-header">
                            <span class="text-gray-300">Properties</span>
                            <button class="text-gray-400 hover:text-white"><i class="far fa-copy"></i></button>
                        </div>
                        <div class="code-content">
                            <pre>management.endpoints.enabled-by-default=true
management.endpoint.health.enabled=true
management.endpoint.metrics.enabled=false</pre>
                        </div>
                    </div>

                    <h3 class="font-bold text-xl mb-4 text-gray-800">设置端点的访问路径</h3>
                    <p class="text-gray-700 mb-6">通过配置可以自定义端点的访问路径。</p>
                    
                    <div class="code-block mb-8">
                        <div class="code-header">
                            <span class="text-gray-300">Properties</span>
                            <button class="text-gray-400 hover:text-white"><i class="far fa-copy"></i></button>
                        </div>
                        <div class="code-content">
                            <pre>management.endpoints.web.base-path=/actuator
management.endpoints.web.path-mapping.health=healthcheck</pre>
                        </div>
                    </div>
                </section>
            </div>
        </div>
    </div>

    <!-- Footer -->
    <footer class="bg-gray-900 text-white py-12">
        <div class="container mx-auto max-w-5xl px-4 text-center">
            <h3 class="text-xl font-bold mb-4">技术小馆</h3>
            <p class="mb-6 text-gray-400">专注于分享前沿技术知识与实践经验</p>
            <a href="http://www.yuque.com/jtostring" class="text-purple-400 hover:text-purple-300 transition duration-300">访问语雀主页 <i class="fas fa-external-link-alt ml-1"></i></a>
        </div>
    </footer>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'dark',
            fontFamily: 'Noto Sans SC, sans-serif'
        });
        
        // 复制代码功能
        document.querySelectorAll('.code-header button').forEach(button => {
            button.addEventListener('click', () => {
                const code = button.parentElement.nextElementSibling.textContent;
                navigator.clipboard.writeText(code).then(() => {
                    const originalIcon = button.innerHTML;
                    button.innerHTML = '<i class="fas fa-check"></i>';
                    setTimeout(() => {
                        button.innerHTML = originalIcon;
                    }, 2000);
                });
            });
        });
    </script>
</body>
</html>